/// Qualab - 24/11/2011

#include <internal/windowdata.h>
#include <wink/app.h>
#include <wink/errors.h>

namespace wink
{
    WindowData::WindowData()
        : mHandle()
    {
    }

    WindowData::WindowData( PString text, int width, int height, int x, int y, int show_mode )
        : mHandle()
    {
        Create( text, width, height, x, y, show_mode );
    }

    WindowData::WindowData( HWND handle )
        : mHandle( handle )
    {
        Reset();
        if( mHandle )
            UpdateRect();
    }

    WindowData::~WindowData()
    {
        Close();
    }

    void WindowData::Create( LPCTSTR text, int width, int height, int x, int y, int show_mode )
    {
        if( mHandle ) Close();

        mHandle = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW, App::ClassName(), text, WS_OVERLAPPEDWINDOW,
                                  x, y, width, height, HWND_DESKTOP, NULL, App::Instance(), NULL );
        if( !mHandle )
            throw ErrorWindowNotCreated();

        ShowWindow( mHandle, show_mode );
        UpdateWindow( mHandle );
        UpdateRect();
    }

    HWND WindowData::Handle() const
    {
        return mHandle;
    }

    const Rect& WindowData::Shape() const
    {
        return mShape;
    }

    const Rect& WindowData::Client() const
    {
        return mClient;
    }

    int WindowData::Left() const
    {
        return mShape.Left();
    }

    int WindowData::Top() const
    {
        return mShape.Top();
    }

    int WindowData::Right() const
    {
        return mShape.Right();
    }

    int WindowData::Bottom() const
    {
        return mShape.Bottom();
    }

    int WindowData::Width() const
    {
        return mShape.Width();
    }

    int WindowData::Height() const
    {
        return mShape.Height();
    }

    int WindowData::ClientWidth() const
    {
        return mClient.Width();
    }

    int WindowData::ClientHeight() const
    {
        return mClient.Height();
    }

    void WindowData::UpdateRect()
    {
        GetWindowRect( mHandle, &mShape );
        GetClientRect( mHandle, &mClient );
    }

    void WindowData::Close()
    {
        if( mHandle )
        {
            DestroyWindow( mHandle );
            Reset();
        }
    }

    void WindowData::Reset()
    {
        mHandle = NULL;
        mShape = Rect();
        mClient = Rect();
        memset( &mEvents, 0, sizeof( Events ) );
    }

    void WindowData::SetOnMove( Window::OnMoveProc proc )
    {
        mEvents.OnMove = proc;
    }

    void WindowData::SetOnResize( Window::OnResizeProc proc )
    {
        mEvents.OnResize = proc;
    }

    void WindowData::SetOnMouseLDown( Window::OnMouseLDownProc proc )
    {
        mEvents.OnMouseLDown = proc;
    }

    void WindowData::SetOnMouseLUp( Window::OnMouseLUpProc proc )
    {
        mEvents.OnMouseLUp = proc;
    }

    void WindowData::SetOnClose( Window::OnCloseProc proc )
    {
        mEvents.OnClose = proc;
    }

    int WindowData::OnMove( Window& source )
    {
        return mEvents.OnMove ? mEvents.OnMove( source ) : 0;
    }

    int WindowData::OnResize( Window& source )
    {
        return mEvents.OnResize ? mEvents.OnResize( source ) : 0;
    }

    int WindowData::OnMouseLDown( Window& source, int x, int y )
    {
        return mEvents.OnMouseLDown ? mEvents.OnMouseLDown( source, x, y ) : 0;
    }

    int WindowData::OnMouseLUp( Window& source, int x, int y )
    {
        return mEvents.OnMouseLUp ? mEvents.OnMouseLUp( source, x, y ) : 0;
    }

    void WindowData::OnClose( Window& source )
    {
        if( mEvents.OnClose ) mEvents.OnClose( source );
    }
}
